package cripto.core;

 

import java.io.*;

public class VigenereDescriptado {

	/**
	 * @author KHALID  CHEKROUNI
	 */

	/*****matriz que contendra nuestro alfabeto*****/

	char [][]matriz=new char [26][26];

	/**criptograma*/

	String criptograma=null;

	/**
	 * Metodo contructor
	 * entrada:ninguna
	 * salida:ninguna
	 * descripcion:inicializa una matriz cuadrada de nXn donde n es la cantidad de letras
	 * que estemos ocupando para nuestro alfabeto
	 */

	public VigenereDescriptado()
	{
		int codigo=65;//valor de la A mayuscula
		int interno=0;

		//empezamos a llenar por renglones
		for(int i=0;i<26;i++)
		{
			//con interno llenaremos los renglones y con codigo las columnas
			interno=codigo;

			//Nuestro alfabeto tendra 27 
			for(int j=0;j<26;j++)
			{
				matriz[i][j]=(char)interno;
				interno++;
				//preguntamos si llegamos a la Z
				if(interno>90)
				{
					//SI es asi regresa y comienza de nuevo con A
					interno=65;
				}
			}

			codigo++;
			//Preguntamos si llegamos a la Z
			if(codigo>90)
			{
				//SI es asi regresa y comienza con la A
				codigo=65;
			}
		}
	}

	/**
	 *Funcion quitaEspacios
	 *entrada:una cadena de texto
	 *salida:una cadena de texto
	 *descripcion:Funcion que nos quita los espacios en blanco,se ingresa una cadena problema
	 *que contiene espacios en blanco y devuelve una cadena problema sin espacios en blanco 
	 */
	String quitaEspacios(String problema)
	{
		char []auxiliar=problema.toCharArray();
		problema="";
		for(int i=0;i<auxiliar.length;i++)
		{
			if(auxiliar[i]!=' ')
			{
				problema+=auxiliar[i];

			}
		}
		return problema;
	}

	/**
	 * Funcion completa
	 */

	public String completa(String faltante,int tamano)
	{
		int diferencia=0,indice=0;
		if(faltante.length()!=tamano)
		{
			//preguntamos si es menor la clave al mensaje
			if(faltante.length()<tamano)
			{
				//Tenemos que acompletar
				//obtenemos la diferencia 
				diferencia=tamano-faltante.length();
				while(diferencia!=0)
				{
					faltante+=faltante.charAt(indice);
					//preguntamos si es el final de la cadena
					if(indice==(faltante.length()-1))
					{
						indice=-1;
					}
					indice++;
					diferencia--;
				}
			}
			else
			{
				//Tenemos que acortar
				//obtenemos lo que nos sobra
				diferencia=faltante.length()-tamano;
				//cortamos la cadena
				faltante=faltante.substring(0, faltante.length()-diferencia);
			}
		}
		return faltante;
	}

	/**
	 * Funcion getCaracter
	 * entrada:dos argumentos,el primero de tipo char que representa la i-esima letra que
	 * conforma el mensaje,elsegundo representa la k-esima que conforma la clave
	 * salida:un argumento de tipo char,que representa la interseccion entre las columnas
	 * del mensaje y de la clave
	 * descripcion:busca en las columnas el argumento mensaje y obtiene su posicion,busca en 
	 * los renglones el argumento clave y obtiene su posicion en base a eso identfica
	 * el caracter y lo retorna
	 */

	char getCaracterDescifrado(char cripto,char clave)
	{
		//variables auxiliares
		int posicionMensaje=0,posicionClave=0,indice=0;
		boolean encontrado=false;

		//buscamos el caracter del mensaje en la columna del criptograma
		while(indice<26 && encontrado==false)
		{
			if(matriz[0][indice]==clave)
			{
				encontrado=true;
				posicionClave=indice;
			}

			indice++;
		}
		encontrado=false;
		indice=0;
		//buscamos el caracter en el renglon de las claves
		while(indice<26 && encontrado==false)
		{
			if (matriz[indice][posicionClave]==cripto)
			{
				encontrado=true;
				posicionMensaje=indice;
			}
			indice++;
		}
		//Nos aseguramos que hayamos obtenido algun resultado
		return matriz[0][posicionMensaje];
	}

	/**
	 * Metodo descifra
	 * entrada:dos arguementso de tipo string,el primero contiene el mensaje a cifrar y el
	 * segundo la clave que se usara
	 * salida:una cadena que representa el criptograma
	 * descripcion:Cifra una cadena usando la clave con el algoritmod de vigenere
	 */

	public String descifra(String mensaje,String clave)
	{
		criptograma=" ";
		//Quitamos espacios en blanco de la clave y del mensaje
		mensaje=quitaEspacios(mensaje);
		clave=quitaEspacios(clave);

		//Convertimos a mayusculas el mensaje y la clave
		mensaje=mensaje.toUpperCase();
		clave=clave.toUpperCase();

		//Completamos el tamano de la clave al tamano del mensaje
		clave=completa(clave,mensaje.length());

		//aplicamos el algoritmo de Vigenere
		for(int i=0;i<mensaje.length();i++)
		{
			//Obtenemos el caracter segun la matriz de vigenere
			//que es la interseccion de la columna del mensaje y la columna
			//de las claves y la concatenamos con el criptograma
			criptograma+=getCaracterDescifrado(mensaje.charAt(i),clave.charAt(i));
		}


		return criptograma;
	}//fin del metodo cifra

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		try{
			InputStreamReader teclado=new InputStreamReader(System.in);
			BufferedReader buffer=new BufferedReader(teclado);
			/********************************************************
			 **Variables auxiliares para interactuar con el usuario**
			 ********************************************************/
			String mensaje_claro;
			String clave;

			/*****************************************
			 **Pedimos al usuario ingresar los datos**
			 *****************************************/
			System.out.println("Introduzca el criptograma");
			mensaje_claro=buffer.readLine();
			mensaje_claro=mensaje_claro.trim();
			System.out.println("Introduzca la llave");
			clave=buffer.readLine();

			// Instanciacion de la clase
			VigenereDescriptado metodo=new VigenereDescriptado();

			System.out.println("Mcla:"+metodo.descifra(mensaje_claro,clave));
		}
		catch(Exception e)
		{
			System.out.println("Ocurrio un error "+e);
		}



	}

}



